package com.foton.bpc.all.remoting.netty;

import com.foton.bpc.all.remoting.Server;
import com.foton.bpc.all.remoting.netty.adpect.HandlerAdpect;
import com.foton.bpc.all.remoting.netty.codec.Codec;
import com.foton.bpc.all.remoting.netty.handler.NettyCodecHandler;
import com.foton.bpc.all.remoting.netty.handler.NettyLogicHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.extern.slf4j.Slf4j;

import java.net.InetSocketAddress;
import java.net.URI;

/**
 * @Author RenPu
 * @Date 2023/6/5 16:43
 * @Version 1.0
 * @Description: Netty服务端端（服务提供者）
 * 底层网络框架基于Netty的实现方式
 **/

@Slf4j
public class NettyServer implements Server {

    //开启网络服务
    //创建事件循环组
    EventLoopGroup boss=new NioEventLoopGroup();   //事件监听组
    EventLoopGroup work=new NioEventLoopGroup();   //事件处理组
    @Override
    public void start(URI uri, Codec codec, HandlerAdpect handlerAdpect) {

        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap.group(boss,work)
                 //指定chanel得类型
                 .channel(NioServerSocketChannel.class)
                 //监听地址
                 .localAddress(new InetSocketAddress(uri.getHost(),uri.getPort()))
                 //添加handler处理器，有链接后触发处理器
                 .childHandler(new ChannelInitializer<SocketChannel>() {

                     @Override
                     protected void initChannel(SocketChannel ch) throws Exception {
                         ch.pipeline()
                                 //处理编解码处理器,避免线程安全问题，每次初始化编解码器对象
                                 .addLast(new NettyCodecHandler(codec.creteInstance()))
                                 //具体业务逻辑得处理
                                 .addLast(new NettyLogicHandler(handlerAdpect));
                     }
                 });

        try {
            ChannelFuture future = bootstrap.bind().sync();
            log.info("netty：：：绑定端口和启动网络服务成功");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


    }
}
